<?php

namespace App\Models\Mp;

use App\Lib\WeApp\WeApp;
use App\Wen\Utils\StrUtils;
use Dcat\Admin\Traits\HasDateTimeFormatter;

use Dcat\Admin\Traits\ModelTree;
use DOMDocument;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Spatie\EloquentSortable\Sortable;

class WxMpFreePublish extends Model implements Sortable
{
	use HasDateTimeFormatter;
    use ModelTree;

    protected $table = 'wx_mp_free_publish';

    public function normal(){
        return [
            'title' => StrUtils::limit($this->title, 30),
            'author' => $this->author,
            'digest' => $this->digest,
            'content' => self::mediaImgProcess($this->content, true),
            'content_source_url' => $this->content_source_url,
            'thumb_media_id' => $this->thumb_media_id,
            'need_open_comment' => $this->need_open_comment,
            'only_fans_can_comment' => $this->only_fans_can_comment,
            'pic_crop_235_1' => $this->pic_crop_235_1,
            'pic_crop_1_1' => $this->pic_crop_1_1
        ];
    }

    protected static function boot()
    {
        parent::boot();

        static::creating(function ($model) {
            $weapp = new WeApp('mp');
            $mp = $weapp->getMpServicer();
            if($model->thumb_url){
                $thumb_url = $model->thumb_url;
                try {
                    // 获取远程图片内容
                    $res = $mp->uploadMaterial($thumb_url);
                    if($res['code'] == 200){
                        $model->thumb_media_id = $res['media_id'];
                        list($img_width, $img_height, $type, $attr) = getimagesize($thumb_url);
                        if($img_width > 0 && $img_height > 0){
                            $coordinates235 = self::calculateCropCoordinates($img_width, $img_height, 2.35, 1);
                            $model->pic_crop_235_1 = $coordinates235['x1'].'_'.$coordinates235['y1'].'_'.$coordinates235['x2'].'_'.$coordinates235['y2'];
                            $coordinates11  = self::calculateCropCoordinates($img_width, $img_height, 1, 1);
                            $model->pic_crop_1_1 = $coordinates11['x1'].'_'.$coordinates11['y1'].'_'.$coordinates11['x2'].'_'.$coordinates11['y2'];
                        }
                    }else{
                        throw new \Exception($res['msg']);
                    }
                }catch (\Exception $e){
                    _logger_(__file__, __line__, $e->getMessage());
                }

                if($model->content){
                    $model->content = self::mediaImgProcess($model->content);
                }

            }else{
                throw new \Exception('请上传封面');
            }

        });

        static::created(function ($model) {
            if(_empty_($model->parent_id)){
                $minOrder = WxMpFreePublish::min('order');
                if(_empty_($minOrder)){
                    $minOrder = 0;
                }
                WxMpFreePublish::where('id', $model->id)
                    ->update(['order' => $minOrder - 1]);
            }else{
                // 有父级
                $update_media_id = WxMpFreePublish::where('id', $model->parent_id)->value('media_id');
                if($update_media_id){
                    $weapp = new WeApp('mp');
                    $mp = $weapp->getMpServicer();
                    // 需要更新
                    $mp->deleteDraft($update_media_id);
                    WxMpFreePublish::where('id', $model->parent_id)->update([ 'media_id' => null ]);
                    // 更新草稿
                    $mp->addOrUpdateDraft($model->parent_id);
                }
            }
        });

        static::updating(function ($model) {
            // 在模型更新之前触发的操作
            $model->original = $model->getOriginal();
            if($model->content){
                $model->content = self::mediaImgProcess($model->content);
            }
        });

        static::updated(function ($model) {
            $original = $model->original;
            $changes = $model->getChanges();

            $weapp = new WeApp('mp');
            $mp = $weapp->getMpServicer();

            // 对比更新前后的字段
            $need_update_draft = false;
            foreach ($changes as $key => $value) {
                if(in_array($key, ['title','author','digest','content','content_source_url','thumb_url','need_open_comment','only_fans_can_comment'])){
                    $need_update_draft = true;
                }
                if($key == 'thumb_url'){
                    if($value){
                        $thumb_url = $value;
                        try {
                            // 获取远程图片内容
                            $res = $mp->uploadMaterial($thumb_url);
                            $old_thumb_media_id = $model->thumb_media_id;
                            if($res['code'] == 200){
                                $updates = [];
                                $updates['thumb_media_id'] = $res['media_id'];
                                list($img_width, $img_height, $type, $attr) = getimagesize($thumb_url);
                                if($img_width > 0 && $img_height > 0){

                                    $coordinates235 = self::calculateCropCoordinates($img_width, $img_height, 2.35, 1);
                                    $updates['pic_crop_235_1'] = $coordinates235['x1'].'_'.$coordinates235['y1'].'_'.$coordinates235['x2'].'_'.$coordinates235['y2'];
                                    $coordinates11  = self::calculateCropCoordinates($img_width, $img_height, 1, 1);
                                    $updates['pic_crop_1_1'] = $coordinates11['x1'].'_'.$coordinates11['y1'].'_'.$coordinates11['x2'].'_'.$coordinates11['y2'];
                                    WxMpFreePublish::where('id', $model->id)->update($updates);
                                    $mp->deleteMaterial($old_thumb_media_id);
                                }
                            }else{
                                throw new \Exception($res['msg']);
                            }
                        }catch (\Exception $e){
                            _logger_(__file__, __line__, $e->getMessage());
                        }
                    }else{
                        throw new \Exception('请上传封面');
                    }
                }
            }

            if($need_update_draft && $model->media_id){
                $mp->addOrUpdateDraft($model->id);
            }

        });

        static::deleted(function ($model) {

            // 在删除之后执行的逻辑
            $weapp = new WeApp('mp');
            $mp = $weapp->getMpServicer();

            if($model->parent_id > 0){
                if($model->thumb_media_id){
                    $mp->deleteMaterial($model->thumb_media_id);
                }
                $parent_model = WxMpFreePublish::find($model->parent_id);
                // 先删除再更新
                if($parent_model->media_id){
                    $mp->deleteDraft($parent_model->media_id);
                    WxMpFreePublish::where('id', $parent_model->id)->update([ 'media_id' => null ]);
                    // 更新草稿
                    $mp->addOrUpdateDraft($model->parent_id);
                }
            }else{
                if($model->media_id){
                    $mp->deleteDraft($model->media_id);
                }

                if($model->thumb_media_id){
                    $mp->deleteMaterial($model->thumb_media_id);
                }

                WxMpFreePublish::where('parent_id', $model->id)->delete();
            }
        });
    }


    static function mediaImgProcess($html, $wechat = false) {
        $weapp = new WeApp('mp');
        $mp = $weapp->getMpServicer();
        $dom = new DOMDocument('1.0', 'UTF-8');
        // 禁用 libxml 的错误报告，以处理潜在的 HTML 5 标签问题
        libxml_use_internal_errors(true);
        // 加载 HTML 字符串
        $dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
        libxml_clear_errors();

        // 获取所有的 <img> 标签
        $images = $dom->getElementsByTagName('img');
        // 遍历所有的 <img> 标签
        foreach ($images as $img) {
            // 检查是否有 mp-src 属性
            if($wechat){
                if($img->hasAttribute('mp-src')){
                    $mp_src = $img->getAttribute('mp-src');
                    $img->setAttribute('src', $mp_src);
                }
            }else{
                if (!$img->hasAttribute('mp-src')) {
                    $src = $img->getAttribute('src');
                    if($src && strpos($src, 'mmbiz.qpic.cn') === false){
                        if(StrUtils::startsWith($src, 'http')){
                            $res = $mp->uploadMediaImg($src);
                            // 将 mp-src 属性的值设置为 src 属性的值
                            if($res['code'] == 200){
                                $img->setAttribute('mp-src', $res['url']);
                            }
                        }else{

                        }
                    }
                }
            }
        }

        // 处理有 style 属性的标签
        $elements = $dom->getElementsByTagName('*');
        foreach ($elements as $element) {
            if ($element->hasAttribute('style')) {
                $style = $element->getAttribute('style');
                if($wechat){
                    if ($element->hasAttribute('mp-bg-src')) {
                        $mpBgSrc = $element->getAttribute('mp-bg-src');
                        if(!_empty_($mpBgSrc) && StrUtils::startsWith($mpBgSrc, 'http')){
                            if (preg_match('/background-image\s*:\s*url\(([^)]+)\)/', $style, $matches)) {
                                $bgSrc = trim($matches[1], '"\'');
                                if($bgSrc && strpos($bgSrc, 'mmbiz.qpic.cn') === false){
                                    $element->setAttribute('style', str_replace($matches[1], $mpBgSrc, $style ));
                                }
                            }
                        }
                    }
                }else{
                    if (!$element->hasAttribute('mp-bg-src')) {
                        // 查找 background-image 属性
                        if (preg_match_all('/background-image\s*:\s*url\(([^)]+)\)/', $style, $matches)) {
                            foreach ($matches[1] as $bgImageUrl) {
                                if (!$element->hasAttribute('mp-bg-src')) {
                                    $bgSrc = trim($bgImageUrl, '"\'');
                                    if($bgSrc && strpos($bgSrc, 'mmbiz.qpic.cn') === false){
                                        if(StrUtils::startsWith($bgSrc, 'http')){
                                            $res = $mp->uploadMediaImg($bgSrc);
                                            // 将 mp-src 属性的值设置为 src 属性的值
                                            if($res['code'] == 200){
                                                $element->setAttribute('mp-bg-src', $res['url']);
                                            }
                                        }else{

                                        }
                                    }


                                }
                            }
                        }

                        if (preg_match('/background-image\s*:\s*url\(([^)]+)\)/', $style, $matches)) {
                            $bgSrc = trim($matches[1], '"\'');

                        }
                    }
                }

            }
        }

        // 保存处理后的 HTML
        return $dom->saveHTML();
    }

    static function calculateCropCoordinates($width, $height, $ratioWidth, $ratioHeight) {
        // 计算裁剪区域的目标宽高
        $targetRatio = $ratioWidth / $ratioHeight;
        $imageRatio = $width / $height;

        if ($imageRatio > $targetRatio) {
            // 图片过宽，以高度为基准裁剪
            $cropHeight = $height;
            $cropWidth = $cropHeight * $targetRatio;
        } else {
            // 图片过高，以宽度为基准裁剪
            $cropWidth = $width;
            $cropHeight = $cropWidth / $targetRatio;
        }

        // 计算裁剪区域的左上角和右下角坐标
        $x1 = ($width - $cropWidth) / 2;
        $y1 = ($height - $cropHeight) / 2;
        $x2 = $x1 + $cropWidth;
        $y2 = $y1 + $cropHeight;

        // 将坐标归一化到0到1的范围内
        return array(
            'x1' => round($x1 / $width, 6),
            'y1' => round($y1 / $height,6),
            'x2' => round($x2 / $width,6),
            'y2' => round($y2 / $height, 6)
        );
    }

}
